package com.dfbz.dao.Base;

import com.dfbz.annotation.DB;
import com.dfbz.annotation.Filed;
import com.dfbz.utils.JDBCUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class BaseDao<T> {
    private Class<T> tClass;
    private String dbName;
    private String dbId;
    private JdbcTemplate jdbcTemplate;
    public BaseDao(Class<T> tClass){
        this.tClass=tClass;
        DB db = tClass.getAnnotation(DB.class);
        if (null != db){
            dbName=db.table();
            dbId=db.id();
        }
        jdbcTemplate=new JdbcTemplate(JDBCUtil.getDataSource());
    }
    protected JdbcTemplate getJdbcTemplate(){
        return jdbcTemplate;
    }
    public ArrayList<T> findList(){
        ArrayList<T> list=null;
        try {
            list = (ArrayList<T>) jdbcTemplate.query("select * from "+dbName, new BeanPropertyRowMapper<>(tClass));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    public void deleteById(Object id) {
        try {
            jdbcTemplate.update("delete from "+dbName+" where "+dbId+" =?",id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void update(T obj){
        Class<?> objClass = obj.getClass();
        try {
            StringBuilder sb=new StringBuilder();
            sb.append("update ").append(dbName).append(" set ");
            Field[] fields = tClass.getDeclaredFields();
            int length=fields.length;
            int count=0;
            for (int i = 1; i < length; i++) {
                Field field = fields[i];
                String colName=field.getName();
                Filed myField = field.getDeclaredAnnotation(Filed.class);
                String methodName;
                if (null !=myField){
                    colName=myField.value();
                }
                methodName="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
                Method method = objClass.getDeclaredMethod(methodName);
                Object value = method.invoke(obj);
                if (null !=value){
                    sb.append("`").append(colName).append("`").append("=? ,");
                    count++;
                }
            }
            sb.delete(sb.lastIndexOf(","),sb.length());
            sb.append("where ");
            Field firstfield = fields[0];
            String first_colName=firstfield.getName();
            Filed myFirstField = firstfield.getDeclaredAnnotation(Filed.class);
            if (null !=myFirstField){
                first_colName=myFirstField.value();
            }
            sb.append(first_colName).append("=?");
            count++;
            Object[] objects = new Object[count];
            int index=0;
            for (int i = 0; i < length; i++) {
                Field field = fields[i];
                String fieldName = field.getName();
                String methodName;
                methodName="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
                Method method = objClass.getDeclaredMethod(methodName);
                Object value = method.invoke(obj);
                if (null !=value){
                    if (i==0){
                        objects[count-1]=value;
                        //System.out.println(i+">>>>"+value);
                    }
                    else {
                        objects[index]=value;
                        //System.out.println(i+"<<<<"+value);
                        index++;
                    }
                }
            }
//            System.out.println(sb.toString());
//            for (int i = 0; i < objects.length; i++) {
//                System.out.println(objects[i]+"---"+i);
//            }
            jdbcTemplate.update(sb.toString(), objects);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void save(T obj){
        Class<?> objClass = obj.getClass();
        try {
            StringBuilder sb=new StringBuilder();
            Field[] fields = tClass.getDeclaredFields();
            int length=fields.length;
            sb.append("insert into ").append(dbName).append("(");
            Integer count=0;
            for (int i = 0; i < length; i++) {
                Field field = fields[i];
                String colName=field.getName();
                Filed myField = field.getDeclaredAnnotation(Filed.class);
                if (null !=myField){
                    colName=myField.value();
                }
                String methodName="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
                Method method = objClass.getDeclaredMethod(methodName);
                Object value = method.invoke(obj);
                if (null != value){
                    sb.append("`").append(colName).append("`").append(",");
                    count++;
                }

            }
            sb.delete(sb.lastIndexOf(","),sb.length());
            sb.append(") values(");
            for (int i = 0; i < count; i++) {
                if (i == count-1){
                    sb.append("?)");
                }
                else {
                    sb.append("?,");
                }
            }
            Object[] objects = new Object[count];
            for (int i = 0; i < count; i++) {
                Field field = fields[i];
                String fieldName = field.getName();
                String methodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                Method method = objClass.getDeclaredMethod(methodName);
                Object value = method.invoke(obj);
                objects[i]=value;
            }
            jdbcTemplate.update(sb.toString(),objects);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public T findByid(Object id) {
        T t=null;
        try {
            t = jdbcTemplate.queryForObject("select * from "+dbName+" where "+dbId+" =?",new BeanPropertyRowMapper<>(tClass),id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
}
